#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "heat_3d.h"

void init_array(int n, double A[10][10][10], double B[10][10][10]) {
    int i, j, k;

    for (i = 0; i < n; i++)
        for (j = 0; j < n; j++)
            for (k = 0; k < n; k++)
                A[i][j][k] = B[i][j][k] = (double)(i + j + (n - k)) * 10 / (n);
}

void print_array(int n, double A[10][10][10])

{
    int i, j, k;

    fprintf(stderr, "==BEGIN DUMP_ARRAYS==\n");
    fprintf(stderr, "begin dump: %s", "A");
    for (i = 0; i < n; i++)
        for (j = 0; j < n; j++)
            for (k = 0; k < n; k++) {
                if ((i * n * n + j * n + k) % 20 == 0)
                    fprintf(stderr, "\n");
                fprintf(stderr, "%0.6lf ", A[i][j][k]);
            }
    fprintf(stderr, "\nend   dump: %s\n", "A");
    fprintf(stderr, "==END   DUMP_ARRAYS==\n");
}

int main() {
    int n = 10;
    int tsteps = 20;
    int has_errors = 0;

    double A[10][10][10];
    double B[10][10][10];

    char data_buf[256];
    char check_buf[256];

    init_array(n, A, B);

    kernel_heat_3d(A, B);

    FILE *tb_file = fopen("check.data", "r");
    assert(tb_file != NULL && "Couldn't open check data file");

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            for (int k = 0; k < n; k++) {
                sprintf(data_buf, "%0.6lf", A[i][j][k]);
                int res = fscanf(tb_file, "%s", check_buf);
                assert(res == 1 && "read check data file failed");
                if (strcmp(data_buf, check_buf)) {
                    printf("A[%d][%d][%d] = %s, expected_A[%d][%d][%d] = %s\n",
                           i, j, k,
                           data_buf,
                           i, j, k,
                           check_buf);
                    has_errors++;
                }
            }
        }
    }

    fclose(tb_file);

    if (has_errors) {
        fprintf(stderr, "Benchmark results are incorrect\n");
        return -1;
    }

    printf("Success.\n");
    return 0;
}
